package com.sy.server.service.impl;

import com.sy.server.service.IUserService;
import com.sy.server.util.MyConst;
import com.sy.server.dao.RedisDAO;
import com.sy.server.mapper.LoginMapper;
import com.sy.server.mapper.UserMapper;
import com.sy.server.model.Login;
import com.sy.server.model.User;
import com.sy.server.model.UserExample;
import com.sy.server.util.IpUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Service
public class UserService implements IUserService {
    private final Logger logger= LoggerFactory.getLogger(UserService.class);
    @Autowired
    private UserMapper mapper;
    @Autowired
    private LoginMapper lmapper;
    @Autowired
    private RedisDAO rdao;
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private IpService ipService;
    @Value("${md5.key}")
    private String md5Key;

    public int login(User user) {
        if(existUser(user.getUserName())){
            User user1=mapper.selectPasswordByUserName(user.getUserName());
            String passKey=user.getUserName()+user.getPassword()+md5Key;
            String pass=DigestUtils.md5DigestAsHex(passKey.getBytes());
            if(user1.getPassword().equals(pass)){
                String curIp=IpUtil.getIpAddress(request);
                String redisLockKey=curIp+":"+user.getUserName()+ MyConst.LOCK_SUFFIX;
                String redisLockValue=user1.getUserId().toString();
                Set ipSet=rdao.keys(curIp+"*"+MyConst.LOCK_SUFFIX);
                if(!ipSet.isEmpty()){
                    logger.error("当前机器已有用户登录，用户【{}】登录失败。",user.getUserName());
                    return 2;
                }else{
                    //192.168.43.2:songyang-lock
                    Set userSet=rdao.keys("*"+user.getUserName()+MyConst.LOCK_SUFFIX);
                    if(rdao.setNx(user.getUserName()+MyConst.LOGIN_SUFFIX,"login",1000,TimeUnit.MILLISECONDS)){
                        if(!userSet.isEmpty()){
                            //删掉之前的登录状态
                            rdao.deleteString((String)userSet.iterator().next());
                        }
                        //加入新的登录状态
                        if(rdao.setNx(redisLockKey,redisLockValue,20, TimeUnit.HOURS)){
                            //192.168.43.1:songyang-lock
                            String addr=IpUtil.getCityInfo(curIp);
                            if(addr!=null){
                                addr=addr.replace("|","").replace("0","");
                            }
                            Integer userId=user1.getUserId();
                            Login login=new Login();
                            login.setUserId(userId);
                            login.setUserName(user.getUserName());
                            login.setIpAddr(curIp);
                            login.setCityAddr(addr);
                            logger.info("登录成功，登录信息：【{}】，所在地：{}",redisLockKey,addr);
                            if (lmapper.countByUserIdAndIp(userId,curIp)>0) {
                                lmapper.updateLoginTime(login);
                            }else{
                                lmapper.insert(login);
                            }
                            return 0;
                        }
                        logger.error("未知错误！");
                        return 2;
                    }
                    logger.warn("【{}】频繁点击登录或有异地同时登录等异常行为",user.getUserName());
                    return 3;
                }
            }
        }
        return 1;
    }

    public boolean existUser(String userName){
        UserExample example=new UserExample();
        example.createCriteria().andUserNameEqualTo(userName);
        return mapper.countByExample(example)>0;
    }

    public String getUserNameByCurrentIp() {
        logger.info("");
        return ipService.getUserNameByCurrentIp();
    }

    public void logout() {
        String curIp=IpUtil.getIpAddress(request);
        Set set=rdao.keys(curIp+"*"+MyConst.LOCK_SUFFIX);
        if(!set.isEmpty()){
            String info=(String)set.iterator().next();
            logger.info("用户登出成功，登出信息：【{}】",info);
            rdao.deleteString(info);
        }
    }

    public void reg(User user) {
        if(rdao.setNx(user.getUserName()+MyConst.REG_SUFFIX,"reg",1000,TimeUnit.MILLISECONDS)){
            String passKey=user.getUserName()+user.getPassword()+md5Key;
            String pass=DigestUtils.md5DigestAsHex(passKey.getBytes());
            user.setPassword(pass);
            mapper.insert(user);
            logger.info("用户【{}】注册成功",user.getUserName());
        }
        logger.info("用户【{}】注册失败",user.getUserName());
    }
}
